
package model.xmlconvert;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.*;

import nu.xom.Document;
import nu.xom.Element;
import nu.xom.Serializer;

import flowchart.FlowChartConfiguration;

import model.codeconverter.CodeConverter;
import model.event.ModelChangeEvent;
import model.event.ModelComponentChangeListiner;
import model.xmlconvert.ModelLinkFlowChartComponent.ArrowType;

public class ModelFlowChart{

	private ComponentListiner listiner = new ComponentListiner();
	public Map<String, ModelFlowChartComponent> map;
	
	public ModelFlowChart(){
	
		map = new HashMap<String, ModelFlowChartComponent>();
	}
	
	public void addComponent(ModelFlowChartComponent m){
		m.addModelChangeListiner(this.listiner);
		map.put(m.getLabel(), m);
	}
	
	private void format(OutputStream os, Document doc) throws Exception{
		
		Serializer serializer = new Serializer(os, "ISO-8859-1");
		serializer.setIndent(4);
		serializer.setMaxLength(60);
		serializer.write(doc);
		serializer.flush();
	}
	
	private void generateXML() throws Exception{
		
		String tmpDir = FlowChartConfiguration.getValue("tmpdir");
		Element root = new Element("flowchart");
		
		this.generateXML(root, "start");
		//for(ModelFlowChartComponent m : list){
			//root.appendChild(m.getXML());
		//}
		
		for(ModelFlowChartComponent m : map.values()){
			m.setPassed(false);
		}
		
		Document doc = new Document(root);
		this.format(new BufferedOutputStream(new FileOutputStream("flowchart.xml")), doc);
	}
	
	private void generateXML(Element e, String label){
		
		System.out.println(label);
		
		if(label.equals("end"))
			return;
		else if(label.equals("")){
			Element operation = new Element("operation");
			operation.appendChild(map.get(label).getOperation());
			e.appendChild(operation);
			return;
		}
		
		 ModelFlowChartComponent c = map.get(label);
		 
		 if(c.isPassed()){
			 
		 }
		 
		 if(c instanceof ModelDiamondFlowChartComponent){
			 
			 Iterator<ModelLinkFlowChartComponent> l =  c.getComponentConnections();
			 
			 while(l.hasNext()){
				 
				 ModelLinkFlowChartComponent link = l.next();
				 
				 System.out.println(link.getDestination().isPassed());
				 if(!link.getDestination().isPassed()){
					 
					 if(link.getArrowType() == ArrowType.YES){
						 
						 Element ifelement = new Element("if");
						 Element condition = new Element("condition");
						 condition.appendChild(c.getOperation());
						 ifelement.appendChild(condition);
						 c.setPassed(true);
						 this.generateXML(ifelement, link.getDestination().getLabel());
						 e.appendChild(ifelement);
						 
					 }else if(link.getArrowType() == ArrowType.NO){
						 
						 Element elseelement = new Element("else");
						 c.setPassed(true);
						 this.generateXML(elseelement, link.getDestination().getLabel());
						 e.appendChild(elseelement);
					 }
				 }else{
					 
					 //While or do-while loop... :)
				 }
			 }
			 
		 }else{
			 
			 Iterator<ModelLinkFlowChartComponent> l =  c.getComponentConnections();
			 c.setPassed(true);
			 
			 while(l.hasNext()){
				 Element ele = new Element("operation");
				 ele.appendChild(c.getOperation());
				 e.appendChild(ele);
				 
				 generateXML(e, l.next().getDestination().getLabel());
			 }
		 }
	}
	
	private class ComponentListiner implements ModelComponentChangeListiner{

		@Override
		public void changeEvent(ModelChangeEvent e) {
			
			try{
				ModelFlowChart.this.generateXML();
			}catch(Exception e1){
				System.out.println(e1);
			}
		}
	}
}